#ifndef _MAIN_H_
#define _MAIN_H_

#include "game.h"
#include <REGX52.H>
#include <intrins.h>

// 并行8位数据传输
#define LCD_DATA P0

// 片选2引脚，0：片选屏幕右，1：取消片选
sbit LCD_CS2 = P2 ^ 1;
// 片选1引脚，0：片选屏幕左，1：取消片选
sbit LCD_CS1 = P2 ^ 0;
// 使能信号，=1（高电平） 数据准备  =0（低电平）
sbit LCD_E = P2 ^ 4;
// 读/写选择，0：读，1：写
sbit LCD_RW = P2 ^ 3;
// 数据/命令选择，0：命令，1：数据
sbit LCD_RS = P2 ^ 2;

sbit BTN_START = P1 ^ 1;
sbit BTN_PAUSE = P1 ^ 3;
sbit BTN_UP = P1 ^ 7;
sbit BTN_DOWN = P3 ^ 2;
sbit BTN_LEFT = P3 ^ 5;
sbit BTN_RIGHT = P3 ^ 7;

/**
 * 使用一个2byte数据描述一个方块形状，对应一个4x4，一共16个格子区域
 * 换算到显示的像素，每个格子对应4x4像素
 */
uint code TETRIS_SHAPES[7][4] = {
    // I
    {0xF000, 0x4444, 0xF000, 0x4444},
    // L
    {0xE800, 0xc440, 0x2e00, 0x88c0},
    // J
    {0xE200, 0x44c0, 0x8e00, 0xc880},
    // O
    {0xcc00, 0xcc00, 0xcc00, 0xcc00},
    // Z
    {0xc600, 0x4c80, 0xc600, 0x4c80},
    // S
    {0x6c00, 0x8c40, 0x6c00, 0x8c40},
    // T
    {0x4e00, 0x8c80, 0xe400, 0x4c40}};

// 十六个元素，每个代表一行，每行10列，
// 0010 0000 0000 0100 ,中间10位0，每位代表一个4x4像素的格子
uint code GAME_ZONE_INIT_DATA[] = {
    0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, //
    0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004,
    // 多出来3行用来防止数组越界，保持处理逻辑一致
    // 形状是4x4方格，最左上角是坐标原点，允许坐标落到游戏区域的最底端，这时候向下伸出了3行
    0xFFFF, 0xFFFF, 0xFFFF};

struct
{
    uchar shape_type; // 类型
    uchar shape_pos;  // 方位
    uchar x;          // x坐标
    uchar y;          // y坐标
    uint shape;       // 方块的形状数据 4x4 的int数据，每个格子是4x4像素
    uchar next_type;  // 下一个方块的类型
    uchar next_pos;   // 下一个方块的方位
} game_shape;

// 开始画面
#define GAME_STAGE_BEGIN 1
// 速度选择
#define GAME_STAGE_SPEED_CHOOSE 2
// 游戏中
#define GAME_STAGE_PLAY 3
// 游戏结束
#define GAME_STAGE_OVER 4

// 没有按键按下
#define PRESSED_NONE 0
#define PRESSED_START 1
#define PRESSED_PAUSE 2
#define PRESSED_UP 3
#define PRESSED_DOWN 4
#define PRESSED_LEFT 5
#define PRESSED_RIGHT 6

#define BTN_COUNT_DOWN 5000
#define PRESS_ACCELERATION_MAX 8
#define GAME_FRAME_TOTAL 20

/* 下落速度 */
uchar game_speed = 0;

// 游戏得分
uint game_score = 0;

// 消除的行数
uint game_eliminate_lines_count = 0;

// 保存游戏中方块堆积的数据，数据含义和上面的一致
uint idata GAME_ZONE[19];

uchar game_stage = GAME_STAGE_BEGIN;

// 用于生成随机方块和形状的种子
uint game_rand_seed = 0;

/**
 * 持续按下按键，此计数到0时，才返回按键编号
 */
uint game_button_continuous_count = BTN_COUNT_DOWN;
uchar game_pressed_button = PRESSED_NONE;
uchar game_pressed_button_acceleration = 1;

uint game_frame_count = 0;

#endif